using FileSignatures;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using UniversalAdminSystem.Application.FileStorage.Interfaces;
using UniversalAdminSystem.Infrastructure.Configs;

namespace UniversalAdminSystem.Infrastructure.FileStorage;

public class FileValidationService : IFileValidationService
{
    private readonly AllowedFilesConfig _allowedFiles;
    private readonly FileFormatInspector _fileFormatInspector;
    private readonly ILogger<FileValidationService> _logger;

    public FileValidationService(IOptions<AllowedFilesConfig> allowedFiles, ILogger<FileValidationService> logger)
    {
        _allowedFiles = allowedFiles.Value;
        _fileFormatInspector = new FileFormatInspector();
        _logger = logger;
    }

    public (bool isValid, string message, string? format) ValidateFile(string fileName, long fileSize, Stream stream)
    {
        try
        {
            if (stream == null) return (false, "❌ 文件为空", string.Empty);

            // 检查文件大小
            if (fileSize > 100 * 1024 * 1024) return (false, $"❌ 文件大小超过限制：100MB", string.Empty);
            _logger.LogInformation($"大小: {fileSize:N0} bytes ({FormatFileSize(fileSize)})");

            // 检查流状态
            Console.WriteLine($"流状态 - CanRead: {stream.CanRead}, CanSeek: {stream.CanSeek}, Length: {stream.Length}");

            // 允许的无签名类型映射
            var noSignatureMimeMap = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
            {
                { ".txt",  new[] { "text/plain" } },
                { ".md",   new[] { "text/markdown" } },
                { ".json", new[] { "application/json" } },
                { ".xml",  new[] { "application/xml", "text/xml" } }
            };

            // 用 FileSignatures 检测文件签名
            Console.WriteLine("开始检查文件格式...");
            var fileFormat = _fileFormatInspector.DetermineFileFormat(stream);
            Console.WriteLine($"文件格式检测结果: {fileFormat?.MediaType ?? "未知"}");

            Console.WriteLine($"_allowedFiles 是否为空: {_allowedFiles == null}");
            Console.WriteLine($"_allowedFiles.AllowedFiles 是否为空: {_allowedFiles.AllowedFiles == null}");
            Console.WriteLine($"fileFormat.MediaType 是否为空: {string.IsNullOrEmpty(fileFormat?.MediaType)}");


            // 有签名
            if (!string.IsNullOrEmpty(fileFormat?.MediaType) && _allowedFiles.AllowedFiles?.Any(f => f.Mime == fileFormat.MediaType) == true)
            {
                ResetStream(stream);
                return (true, $"✅ 文件校验通过: {fileFormat.MediaType}", fileFormat.MediaType);
            }

            Console.WriteLine($"✅ 文件名称+扩展名：{fileName}");
            // 无签名（比如 txt/md/json/xml），走扩展名映射
            var ext = Path.GetExtension(fileName);
            if (!string.IsNullOrEmpty(ext) && noSignatureMimeMap.TryGetValue(ext, out var mimeList))
            {
                if (mimeList.Any(mime => _allowedFiles.AllowedFiles?.Any(f => f.Mime == mime) == true))
                {
                    ResetStream(stream);
                    return (true, $"✅ 文件校验通过: {string.Join(", ", mimeList)}", mimeList.First());
                }
            }

            return (false, $"❌ 不允许的文件类型: {fileFormat?.MediaType ?? "未知"}", fileFormat?.MediaType);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "文件验证过程中发生异常");
            return (false, $"❌ 文件验证失败: {ex.Message}", string.Empty);
        }
    }

    private string FormatFileSize(long bytes)
    {
        string[] sizes = { "B", "KB", "MB", "GB" };
        double len = bytes;
        int order = 0;
        while (len >= 1024 && order < sizes.Length - 1)
        {
            order++;
            len = len / 1024;
        }
        return $"{len:0.##} {sizes[order]}";
    }
    private void ResetStream(Stream stream)
    {
        if (stream.CanSeek)
            stream.Position = 0;
    }

    // public static bool IsPlainText(Stream stream, int maxBytes = 512)
    // {
    //     stream.Position = 0;
    //     Span<byte> buf = stackalloc byte[maxBytes];
    //     int read = stream.Read(buf);
    //     return !buf[..read].ContainsAny(stackalloc byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 127 });
    // }
}

public record ValidationResult(bool IsValid, string Format, string Message);